package com.example.web.system.service.impl;

import com.example.utils.JwtUtils;
import com.example.utils.RedisConstant;
import com.example.utils.Result;
import com.example.utils.SystemConstant;
import com.example.web.system.entity.LiveUser;
import com.example.web.system.entity.LoginParam;
import com.example.web.system.entity.SysUser;
import com.example.web.system.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

//登录业务
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private JwtUtils jwtUtils;
    @Override
    public Result login(LoginParam loginParam) {
        //校验验证码是否正确
        validCaptcha(loginParam.getCaptchaId(),loginParam.getCaptchaCode());

        //校验用户名密码是否正确
        Authentication authentication=validUsernameAndPassword(loginParam.getUsername(),loginParam.getUserType(),loginParam.getPassword());
        return responseToken(loginParam.getUserType(),authentication);

    }

    @Override
    public Result getInfo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        Map<String,Object> map =new HashMap<>();
        if(principal instanceof LiveUser){
            LiveUser liveUser=(LiveUser)principal;
            map.put("userId",liveUser.getUserId());
            map.put("username",liveUser.getUsername());
            map.put("userType","业主");
            map.put("trueName",liveUser.getTrueName());
            map.put("phone",liveUser.getPhone());
            map.put("sex",liveUser.getSex());
        } else if (principal instanceof  SysUser) {
            SysUser sysUser =(SysUser) principal;
            map.put("userId",sysUser.getUserId());
            map.put("username",sysUser.getUsername());
            map.put("userType","物主");
            map.put("trueName",sysUser.getTrueName());
            map.put("phone",sysUser.getPhone());
            map.put("sex",sysUser.getSex());

        }
        return Result.success(map);
    }

    @Override
    public Result logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal = authentication.getPrincipal();
        if(principal instanceof LiveUser){
            LiveUser liveUser=(LiveUser)principal;
            redisTemplate.delete(RedisConstant.LOGIN_LIVE_USER_PRE+liveUser.getUserId());
        } else if (principal instanceof  SysUser) {
            SysUser sysUser =(SysUser) principal;
            redisTemplate.delete(RedisConstant.LOGIN_SYS_USER_PRE+sysUser.getUserId());

        }
        return Result.success();
    }

    //校验用户名和密码
    private Authentication validUsernameAndPassword(String username, Integer userType, String password) {
        username=username+":"+userType;
        //将用户名和密码封装成token
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken(username,password);
        //进行认证
        Authentication authentication =authenticationManager.authenticate(usernamePasswordAuthenticationToken);

        if(Objects.isNull(authentication)){
            throw  new RuntimeException("用户名或密码错误");
        }
        return authentication;
    }

    //校验验证码
    private void validCaptcha(String captchaId, String captchaCode) {
        //获取redis中存取的验证码内容
        String capchaCode2 = (String) redisTemplate.opsForValue().get(RedisConstant.CAPTCHA_PRE + captchaId);
        if(!captchaCode.equalsIgnoreCase(capchaCode2)){//忽略大小写
            throw  new RuntimeException("验证码错误");
        }
    }

    //响应token
    private Result responseToken(Integer userType,Authentication authentication){
        int userId;
        String username;
        //如果登录的时业主，就将业主信息存入redis中，并响应token数据
        if(userType== SystemConstant.USER_TYPE_YEZHU){
            //获取业主信息
            LiveUser liveUser =(LiveUser) authentication.getPrincipal();
            userId=liveUser.getUserId();
            username=liveUser.getUsername();
            //将业主信息存入redis中
            redisTemplate.opsForValue().set(
                    RedisConstant.LOGIN_LIVE_USER_PRE+userId,
                    liveUser,
                    RedisConstant.LOGIN_LIVE_USER_EXPIRE_TIME,
                    TimeUnit.MINUTES
                    
            );
            //把token响应给前端
            String token = jwtUtils.generateToken(userId, username, userType);
            Map<String,String> map =new HashMap<>();
            map.put("token",token);
            return Result.success(map);
        }
        if (userType==SystemConstant.USER_TYPE_WUZHU){
            //获取物主信息
            SysUser sysUser =(SysUser) authentication.getPrincipal();
            userId=sysUser.getUserId();
            username=sysUser.getUsername();
            //将业主信息存入redis中
            redisTemplate.opsForValue().set(
                    RedisConstant.LOGIN_SYS_USER_PRE+userId,
                    sysUser,
                    RedisConstant.LOGIN_SYS_USER_EXPIRE_TIME,
                    TimeUnit.MINUTES

            );
            //把token响应给前端
            String token = jwtUtils.generateToken(userId, username, userType);
            Map<String,String> map =new HashMap<>();
            map.put("token",token);
            return Result.success(map);

        }
        return Result.error(500,"生成token失败");
    }
}
